package de.godlike.services;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

import org.apache.log4j.Logger;

import de.godlike.services.internal.LogReader;
import de.godlike.services.internal.SysAccessCommon;
import de.godlike.services.internal.SysAccessLinux;
import de.godlike.services.internal.SysAccessWin;
import de.godlike.services.internal.dataTypes.DiskInfo;
import de.godlike.services.internal.dataTypes.LogEntry;
import de.godlike.services.internal.dataTypes.WinProcess;

/**
 * Main-Webservice for all JWebmin-functions.
 * 
 * @author asmodaeus
 * 
 */
@WebService(name = "JWebminService")
public class JWebminService {
	private final Logger logger = Logger.getLogger(JWebminService.class);

	/**
	 * @return the OS-Type (name)
	 */
	@WebMethod
	public String getOsType() {
		this.logger.debug("call to JWebminService.getOsType()");
		return new SysAccessCommon().getOsType();
	}

	/**
	 * @return the cpu-architecture
	 */
	@WebMethod
	public String getArch() {
		this.logger.debug("call to JWebminService.getArch()");
		return new SysAccessCommon().getArch();
	}

	/**
	 * @return the OS-Version
	 */
	@WebMethod
	public String getOsVersion() {
		this.logger.debug("call to JWebminService.getOsVersion()");
		return new SysAccessCommon().getOsVersion();
	}

	/**
	 * @return the current timezone
	 */
	@WebMethod
	public String getTimeZone() {
		this.logger.debug("call to JWebminService.getTimeZone()");
		return new SysAccessCommon().getTimeZone();
	}

	/**
	 * @return the name of the system
	 */
	@WebMethod
	public String getSystemName() {
		this.logger.debug("call to JWebminService.getSystemName()");
		return new SysAccessCommon().getSystemName();
	}

	/**
	 * @return the current IP-address of the system
	 * @throws UnknownHostException
	 */
	@WebMethod
	public String getSystemIp() throws UnknownHostException {
		this.logger.debug("call to JWebminService.getSystemIp()");
		return new SysAccessCommon().getSystemIp();
	}

	/**
	 * Shutdown system.
	 * 
	 * @param seconds2Live
	 *            seconds, until the system goes down (0 = now!)
	 * @return true, if the function is implemented, false otherwise.
	 */
	@WebMethod
	public boolean shutdown(@WebParam(name = "seconds2Live") int seconds2Live) {
		this.logger.debug("call to JWebminService.shutdown(" + seconds2Live
				+ ")");
		if (new SysAccessCommon().isWindows()) {
			new SysAccessWin().shutdown(seconds2Live);
			return true;
		} else {
			new SysAccessLinux().shutdown(seconds2Live);
			return true;
		}
	}

	/**
	 * Restart system.
	 * 
	 * @return true, if the function is implemented, false otherwise.
	 */
	@WebMethod
	public boolean restart() {
		this.logger.debug("call to JWebminService.restart()");
		if (new SysAccessCommon().isWindows()) {
			new SysAccessWin().restart();
			return true;
		} else {
			new SysAccessLinux().restart();
			return true;
		}
	}

	/**
	 * @return a list of all processes currently running on the system or null,
	 *         if the function is not implemented
	 */
	@WebMethod
	public List<WinProcess> getTaskList() {
		this.logger.debug("call to JWebminService.getTaskList()");
		if (new SysAccessCommon().isWindows()) {
			return new SysAccessWin().tasklist();
		}
		return new ArrayList<WinProcess>();
	}

	/**
	 * @param pid
	 *            process-id of the process 2 kill
	 * @return true, if the system killed the process, false otherwise
	 */
	@WebMethod
	public boolean killTask(@WebParam(name = "pid") int pid) {
		this.logger.debug("call to JWebminService.killTask(" + pid + ")");
		if (new SysAccessCommon().isWindows()) {
			return new SysAccessWin().taskkill(pid);
		} else {
			return false;
		}
	}

	/**
	 * @return the list of all Disks/mountpoints known in the OS with infos like
	 *         total/used/free Space (in KB).
	 */
	@WebMethod
	public List<DiskInfo> getDiskList() {
		this.logger.debug("call to JWebminService.getDiskList()");
		if (new SysAccessCommon().isWindows()) {
			return new SysAccessWin().getDiskList();
		} else {
			return new SysAccessLinux().getDiskList();
		}
	}

	/**
	 * @param dir
	 *            in which the number of files should be count
	 * @return the number of files in the given dir or 0, if the dir is not
	 *         valid
	 */
	@WebMethod
	public int listDirCount(@WebParam(name = "dir") String dir) {
		this.logger.debug("call to JWebminService.listDirCount(" + dir + ")");
		return new SysAccessCommon().listDirCount(dir);
	}

	/**
	 * @param dir
	 *            2 list.
	 * @return a list of File-Objects found under the passed directory
	 */
	@WebMethod
	public List<de.godlike.services.internal.dataTypes.File> listDir(
			@WebParam(name = "dir") String dir) {
		this.logger.debug("call to JWebminService.listDir(" + dir + ")");
		return new SysAccessCommon().listDir(dir);
	}

	/**
	 * @param dir
	 *            2 list.
	 * @return a list of Files (only names) found under the given directory
	 */
	@WebMethod
	public List<String> listDirOnlyFileNames(@WebParam(name = "dir") String dir) {
		this.logger.debug("call to JWebminService.listDirOnlyFileNames(" + dir
				+ ")");
		return new SysAccessCommon().listDirOnlyFileNames(dir);
	}

	/**
	 * @return the logFile of this service.
	 */
	@WebMethod
	public List<LogEntry> getJWebminServiceLog() {
		return new LogReader().getLogEntries();
	}
}
